#!/usr/bin/ruby

def stop_grader
  File.open(File.dirname(__FILE__) + '/stop','w').close
end

def check_stopfile
  FileTest.exist?(File.dirname(__FILE__) + '/stop')
end

def clear_stopfile
  system("rm " + File.dirname(__FILE__) + '/stop')
end

def config
  Grader::Configuration.get_instance
end

def log_file_name
  config.log_dir + 
    "/#{GRADER_ENV}_#{config.grader_mode}.#{Process.pid}"
end

def log(str)
  if config.talkative
    puts str
  end
  if config.logging
    fp = File.open(log_file_name,"a")
    fp.puts("GRADER: #{Time.new.strftime("%H:%M")} #{str}")
    fp.close
  end
end

def display_manual
  puts <<USAGE
Grader.
using: (1) grader 
       (2) grader environment [mode]
       (3) grader stop
       (4) grader --help
(1) call grader with environment = 'exam', mode = 'queue'
(2) possible modes are: 'queue', 'prob', 'test_request'
(3) create stop-file to stop running grader in queue mode
(4) You are here.
USAGE
end

#########################################
# main program
#########################################

# with --help
if (ARGV.length==1) and (/help/.match(ARGV[0]))
  display_manual
  exit(0)
end

# reading environment and options
if (ARGV.length >= 1) and (ARGV[0]=='stop')
  stop_grader
  puts "stop file created"
  exit(0)
end

if check_stopfile
  puts "stop file exists"
  clear_stopfile
  exit(0)
end

grader_mode = 'queue'
if ARGV.length >= 1
  GRADER_ENV = ARGV[0]
  if ARGV.length >=2
    grader_mode = ARGV[1]
  end
else
  GRADER_ENV = 'exam'
end

puts "environment: #{GRADER_ENV}"
require File.join(File.dirname(__FILE__),'config/environment')

# add grader_mode to config
# this is needed because method log needs it.  TODO: clean this up
class << config
  attr_accessor :grader_mode
end
config.grader_mode = grader_mode

# reading rails environment
log 'Reading rails environment'

RAILS_ENV = config.rails_env
require RAILS_ROOT + '/config/environment'

# register grader process
if config.report_grader
  grader_proc = GraderProcess.register(config.grader_hostname,
                                       Process.pid,
                                       grader_mode)
else
  grader_proc = nil
end

#set loggin environment
ENV['GRADER_LOGGING'] = log_file_name

#
# MAIN LOOP
#

case grader_mode
when "queue", "test_request"
  log "Grader: #{grader_mode}"
  if grader_mode=="queue"
    engine = Grader::Engine.new
  else
    engine = Grader::Engine.new(Grader::TestRequestRoomMaker.new,
                                Grader::TestRequestReporter.new)
  end

  runner = Grader::Runner.new(engine, grader_proc)
  while true
    
    if check_stopfile    # created by calling grader stop
      clear_stopfile
      log "stopped (with stop file)"
      break
    end
    
    if grader_mode=="queue"
      task = runner.grade_oldest_task
    else
      task = runner.grade_oldest_test_request
    end
    if task==nil
      sleep(1)
    end
  end
  
when "prob"
  engine = Grader::Engine.new
  runner = Grader::Runner.new(engine, grader_proc)

  grader_proc.report_active if grader_proc!=nil

  prob = Problem.find_by_name(ARGV[2])
  if prob==nil
    puts "cannot find problem: #{ARGV[2]}"
  else
    runner.grade_problem(prob)
  end

else
  display_manual
  exit(0)
end

# report inactive
grader_proc.report_inactive if grader_proc!=nil
                             
